📓 en/04 - Documentation technique/process/SearchObj.md by @communecter ☆

SearchObj

https://codimd.communecter.org/NFl7lijvQCSUeQ_x-jLSPQ?view

Configuration de l’objet SearchObj - Options (filters.js)

L’objet searchObj inclut beaucoup de mĂ©thodes allant des vues au events liĂ©s aux filtres,Ă  l’algorithme de recherche js Ă  l’affichage des rĂ©sultats Cet objet permet d’unifier toutes les dĂ©pences aux logiques de filtres et de recherche comme pour les espaces d’administration, les applications de recherche (search, agenda, live, dashboard, answer, etc) et les communautĂ©s

I - Arborescence central de l’objet

|_ filters : Object contient toutes les vues des filtres et ces fonctionnalitĂ©s liĂ©es |_ header : Object contient toutes les vues et fonctionnalitĂ© de l’en-tĂȘte de la recherce |_ search : Object contient l’ingĂ©nieurie de recherche de l’initialisation des parametres, la rĂ©cupĂ©ration/traitement des donnĂ©es et fonction de callback |_ results : Object contenant les mĂ©thodes de traitement de la donnĂ©e et d’affichage dans son contenu

II - Options builder (ex : co2/views/app/filters/search)

Plusieurs options de configurations peuvent ĂȘtre envoyĂ©e Ă  l’init du searchObj reprĂ©sentĂ© par la variable pInit
La liste décrite ci-jointe est non exhaustive et pourra laisser place à encore beaucoup de configuration :

III - Filtres dans l’objet

Comme vu ci-dessus, le searchObj.filters gĂ©re Ă  partir de la liste envoyĂ©e l’affichage et les Ă©vĂ©nements des filtres afin de peupler ou dĂ©peupler searchObj.search.obj qui lui communique avec la partie mĂ©tier

3.1 Vues dans filters

A l’initialisation de l’instance, le systĂšme va boucler sur la liste des filtres appelĂ©s pour crĂ©er leur vue.

Exemple la liste des filtres dans ctenational #territoires:

domainAction : {
    view : "dropdownList",
    type : "tags",
    name : "Domaine d'action",
    event : "tags",
    list : costum.lists.domainAction
},
cibleDD:{
    view : "dropdownList",
    type : "tags",
    name : "Objectif",
    event : "tags",
    list : costum.lists.cibleDD
},
scope : true,
scopeList : {
    name : "Région",
    params : {
        countryCode : ["FR","RE","MQ","GP","GF","YT"], 
        level : ["3"]
    }
}

Dans les diffĂ©rents objets, si l’objet Ă  une entrĂ©e view alors il va chercher la vue en question.

Exemple pour domainAction il ira chercher la vue dans la function searchObj.filters.views.dropdownList()

On peut aussi lui donnĂ©e une entrĂ©e dom spĂ©cifique pour qu’il aille dans un container diffĂ©rent que dĂ©finit Ă  l’init avec pInit.container

Pareil, pour la clĂ© scope qui est un boolean, il ira chercher la vue searchObj.filters.views.scope(). Ainsi si l’entrĂ©e view n’est pas dĂ©finit. le systĂšme recherche avec la clĂ© directement

3.2 Evenement pour les filters

De nombreux Ă©vĂ©nements sont disponibles avec une initialisation qui est similaires aux vues. Le systĂšme boucle sur la liste. Si les filtres prĂ©sents ont une entrĂ©e event il va recherche la fonction searchObj.filters.events[v.event] sinon il recherchera Ă  partir de la clĂ©. Certains evenements sont trĂšs spĂ©cifique Ă  une entrĂ©e comme text, price, scope et d’autres vont ĂȘtre spĂ©cifiques Ă  des maniĂšres d’envoyer la donnĂ©e pour la recherche comme exists ou encore inArray

3.3 Field, key and value

Chaque filtre contient un field par dĂ©faut la clĂ© qui dĂ©finir l’attribut sur lequel on recherche en db

{
    name
    tags
    locality
    type
    filters : ^entrée fourre tout pour la recherche^
        {
            links.members.{$id} : {$exists : true}
        }
}

GĂ©nĂ©ralement l’attribut field est le mĂȘme l’ensemble du filtre. Or on peut maintenant pour un mĂȘme liste de filtres dĂ©finir des fields diffĂ©rents comme pour mes communautĂ©s ^[co2/assets/default/profilSocial.js]^

filters.status = {
    view : "dropdownList",
    type : "filters",
    name : "Statuts",
    action : "filters",
    typeList : "object",
    event : "exists",
    list :  {
        "admin" : {
            label: "Administrateur",
            field : "links.memberOf.{$idOrga}.isAdmin",
            count : 130 
            value : true
        },
        "members" : {
            label: "membre",
            field : "links.memberOf.{$idOrga}.isInviting&&links.memberOf.{$idOrga}.toBeValidated",
            value : false,
            count : 20 
        },
        "isInviting": {
            label:"Invitation non confirmée",
            field : "links.memberOf.{$idOrga}.isInviting",
            value : true,
            count : 0 
        },
        "toBeValidated": {
            label:"En attente de validation",
            field : "links.memberOf.{$idOrga}.toBeValidated",
            value : true,
            count : 197
        }
    }
}

3.4 Comportement d’activation des filtres

Les listes de filtres peuvent ĂȘtre affichĂ©es en dropdown ou en liste toute visible ou encore en liste dropable. Ainsi leur comportement d’activation sera diffĂ©rents bien que les attributs eux utilisĂ©s dans l’algo reste les mĂȘmes. On ajoutera l’attribut active : true si l’on veut que qu’il ajoute une classe active au filtre clique. Sinon il ajoutera un bouton d’activation

Les deux fonctions centrales liées aux événements des filtres sont

IV - searchObj.search la logique js de recherche

Le search contient l’algorithme qui permet de traiter la donnĂ©e afin de l’envoyer au controleur dĂ©finit par pInit.urlData donnĂ© Ă  l’initialisation de l’objet et de traiter la donnĂ©e afin de l’envoyer au searchObj.results.render .

Il gére aussi les différents processus de début de fin et les condition de lancement de la recherche.

searchObj.search.multiCols [object of methods] contient un algorithme qui permet de mixer les rĂ©sultats de diffĂ©rentes collections en les ordonnant par nom ou par date. Cette mĂ©thode de mix ne marche qu’avec le scroll et non la pagination.

searchObj.search.obj est l’objet final avec les params envoyĂ© en requete POST. Il passe par un constructUrlAndData pour envoyer les bonnes donnĂ©es et pour envoyer les params dans l’url (mĂ©thode manageHistory)

V - Les comportements du moteur de recherche

Différents objets sont présent

 [] Live 
     { objet permettant la gestion de fil d'actus}
     [modules/news/views/co/index.php]
 [] Agenda 
     {object permettant de rajouter les méthodes spécifique au fonctionnement de l'angenda type scroll}
     [modules/co2/app/filters/agenda.php]
 [] Admin 
      {objet contenant les méthodes spécifuques au espace admin il permet de rediriger sur les vues tableau et les actions liées à l'objet adminDirectory dans co2/assets/admin/directory.js}
 [] Scroll 
     { objet spécifique au fonctionnement d'affichage et de chargement des résultats en scrollant}
 [] Pagination 
     {contient le process permetant la recherche par page}
      

Toutes ces mĂ©thodes dĂ©finies par le paramĂštre loadEvent permettent de surcharger ou de modifier le comportement globale du searchObj notament pour l’affichage des rĂ©sultats ou la maniĂšre dont on met en route ou on finit les processus de recherche

Cette partie du code pourrait ĂȘtre cleanĂ©e/unifier afin de rendre ces mĂ©thode surchargeable dans les options d’initialisation

exemple pInit.search.successComplete : function();
         pInit.search.initProcess : function();
          pInit.search.prepData : function();
           pInit.search.callback : function();
            pInit.results.render : function();
             pInit.results.beforeRender : function();
              pInit.results.afterRender : function();

Voici une liste de fonctions qui pourrait ĂȘtre interprĂ©tĂ©es comme mĂ©thode dans l’objet d’initialisation Ces mĂ©thodes sont aujourd’hui interprĂ©tĂ©es (pas avec les mĂȘmes noms) par le systĂšme via le loadEvent utilsĂ© exemple searchObj.live.successComplete();

exemple

filtre sur une page dashboard

https://cte.ecologique-solidaire.gouv.fr/#dashboard dans un fichier php en render l’url qui sera appelĂ© a chaque changement de filtre sera baseUrl+"/costum/ctenat/dashgraph" et dans filter.js il ne se passe encore pas grand chose

<div id="filters-dash" class="col-xs-12 searchObjCSS">
    
</div>

<div id="dashboardContainer">

</div>

<script type="text/javascript">
    alert("dashboardFilters");
    var paramsSearch = {
        container : "#filters-dash",
        urlData : baseUrl+"/costum/ctenat/dashgraph",
        loadEvent: {
            default : "dashboard",
            eventType: "scroll",
            eventTarget: null,  
        },
        dashboard : {
            options:{}
        }, 
        results : {
            dom : "#dashboardContainer"
        },
        filters : {
            text : true,
            scope : true,
            themes : {
                lists : <?php echo json_encode(CO2::getContextList("filliaireCategories")) ?>
            }
                    
        }
    };

    var filterSearch={};

    jQuery(document).ready(function() {

        mylog.log("render","/modules/costum/views/custom/ctenat/dashboardFilters.php");
        filterSearch = searchObj.init(paramsSearch);
        filterSearch.search.init(filterSearch);
    });

    
</script>

dans filter.js

dashboard : {
		options : {},
		successComplete : function(fObj, data){
			//alert(fObj.search.loadEvent.default);
			fObj.search.currentlyLoading = true;
			$(fObj.results.dom).find(".loader").remove();
    		$(fObj.results.dom+" .processingLoader").remove();
        	$(fObj.results.dom).append(data);
        	
		}
	},